package com.boilermaker.mq.mqserver.manager;

import com.boilermaker.mq.MqApplication;
import com.boilermaker.mq.mqserver.core.Binding;
import com.boilermaker.mq.mqserver.core.Exchange;
import com.boilermaker.mq.mqserver.core.ExchangeType;
import com.boilermaker.mq.mqserver.core.MSGQueue;
import com.boilermaker.mq.mqserver.mapper.MetaMapper;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.List;

/*
 * 进一步封装数据库操作
 */
@Slf4j
public class DataBaseManager {
    private MetaMapper metaMapper;

    // 初始化数据库
    // 建表 + 插入默认数据，封装了 MetaMapper 的前三个操作
    public void init() {
        metaMapper = MqApplication.context.getBean(MetaMapper.class);
        if (!checkDataBaseExists()) {
            File dataDir = new File("./data");
            dataDir.mkdirs();
            createTable();
            insertDefaultData();
            log.info("初始化数据库完成");
        } else {
            log.info("数据库已存在");
        }
    }

    // 删除数据库 （删除 meta.db 文件）
    public void delete() {
        // 删除文件前需要先关闭上下文：
        // 此时 context 持有 MetaMapper 的实例，MetaMapper 操作数据库会使用 meta.db 文件
        // Windows 规定使用中的文件不可被删除，因此先关闭 context，MetaMapper 的实例会销毁
        MqApplication.context.close();
        // 删除数据库文件
        File dataFile = new File("./data/meta.db");
        if (dataFile.delete()) {
            log.info("已删除数据库");
        } else {
            log.info("删除数据库失败");
        }
        // 删除数据库目录
        File dataDir = new File("./data");
        if (dataDir.delete()) {
            log.info("已删除数据库目录");
        } else {
            log.info("删除数据库目录失败");
        }
    }

    public void insertExchange(Exchange exchange) {
        metaMapper.insertExchange(exchange);
    }

    public void insertQueue(MSGQueue msgQueue) {
        metaMapper.insertQueue(msgQueue);
    }

    public void insertBinding(Binding binding) {
        metaMapper.insertBinding(binding);
    }

    public void deleteExchange(String name) {
        metaMapper.deleteExchange(name);
    }

    public void deleteQueue(String name) {
        metaMapper.deleteQueue(name);
    }

    public void deleteBinding(Binding binding) {
        metaMapper.deleteBinding(binding);
    }

    public List<Exchange> selectAllExchanges() {
        return metaMapper.selectAllExchanges();
    }

    public List<MSGQueue> selectAllQueue() {
        return metaMapper.selectAllQueue();
    }

    public List<Binding> selectAllBinding() {
        return metaMapper.selectAllBinding();
    }

    // 为数据库添加默认数据
    // 默认情况下会自动添加一个匿名的 DIRECT 交换机
    private void insertDefaultData() {
        Exchange exchange = new Exchange();
        exchange.setName("");
        exchange.setType(ExchangeType.DIRECT);
        exchange.setDurable(true);
        exchange.setAutoDelete(false);
        metaMapper.insertExchange(exchange);
        log.info("为数据库添加默认数据");
    }

    private void createTable() {
        metaMapper.createQueueTable();
        metaMapper.createBindingTable();
        metaMapper.createExchangeTable();
        log.info("创建数据表");
    }

    private boolean checkDataBaseExists() {
        File file = new File("./data/meta.db");
        return file.exists();
    }
}
